﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using DevComponents.AdvTree;
using ESRI.ArcGIS.Carto;
using PlanningGIS.ArcGIS.Custom;
using ESRI.ArcGIS.Controls;
using System.IO;
using System.Drawing;
using System.Windows.Forms;
using PlanningGIS.ArcGIS;
using ESRI.ArcGIS.Geodatabase;

namespace PlanningGIS.Engine.Controls
{
    /// <summary>
    /// 图层树控件。
    /// 
    /// </summary>
    public partial class LayersTree : AdvTree
    {
        /// <summary>
        /// 构造函数
        /// </summary>
        public LayersTree()
        {
            _Layers = new LayersBase()
            {
                CheckBoxVisiable = true,
                HasRoot = true
            };
            InitializeComponent();

            this.DragDropEnabled = false;
            //this.FeatureType = zjgisFeatureType.zjgisFeatureAll;
            //this.ShapeType = zjgisShapeType.zjgisShapeAll;
            _Layers.Nodes = this.Nodes;

            SetStyle(System.Windows.Forms.ControlStyles.AllPaintingInWmPaint | System.Windows.Forms.ControlStyles.OptimizedDoubleBuffer |
                 System.Windows.Forms.ControlStyles.ResizeRedraw | System.Windows.Forms.ControlStyles.UserPaint, true);

            this.AfterCheck += new AdvTreeCellEventHandler(LayersTree_AfterCheck);
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="container"></param>
        public LayersTree(IContainer container)
            : this()
        {
            container.Add(this);

            //InitializeComponent();
        }

        #region 属性、变量
        /// <summary>
        /// 图层基本对象
        /// </summary>
        private LayersBase _Layers = null;

        /// <summary>
        /// 图层组是否可选
        /// </summary>
        private bool _CompositeLayerEnabled = true;
        /// <summary>
        /// 获取或设置需要控制的图层类型
        /// </summary>
        [Description("设置需要控制的图层数据类型")]
        [DefaultValue(zjgisFeatureType.All)]
        public zjgisFeatureType FeatureType
        {
            get { return _Layers.FeatureType; }
            set { _Layers.FeatureType = value; }
        }

        /// <summary>
        /// 获取或设置需要控制的图层空间数据类型
        /// </summary>
        [Description("设置需要控制的图层空间数据类型")]
        [DefaultValue(zjgisShapeType.All)]
        public zjgisShapeType ShapeType
        {
            get { return _Layers.ShapeType; }
            set { _Layers.ShapeType = value; }
        }
        /// <summary>
        /// 获取或设置是否只显示可见图层
        /// </summary>
        [Description("获取或设置是否只显示可见图层")]
        [DefaultValue(false)]
        public bool IsOnlyVisiable
        {
            get { return _Layers.IsOnlyVisiable; }
            set
            { _Layers.IsOnlyVisiable = value; }
        }

        /// <summary>
        /// 获取或设置图层组是否可选
        /// </summary>
        [Description("获取或设置图层组是否可选")]
        public bool CompositeLayerEnabled
        {
            get { return _Layers.CompositeLayerEnabled; }
            set
            {
                _CompositeLayerEnabled = value;
                _Layers.CompositeLayerEnabled = _CompositeLayerEnabled;
            }
        }

        /// <summary>
        /// 获取或设置是否只显示可选图层
        /// </summary>
        [Description("获取或设置是否只显示可选图层")]
        [DefaultValue(false)]
        public bool IsOnlySelected
        {
            get { return _Layers.IsOnlySelected; }
            set { _Layers.IsOnlySelected = value; }
        }
        #endregion

        /// <summary>
        /// 绑定地图对象
        /// </summary>
        /// <param name="hook">需要绑定的对象：AxMapControl.Object</param>
        /// <param name="tocObject">toc控件的object</param>
        public void OnCreate(object hook, object tocObject = null)
        {
            _Layers.CompositeLayerEnabled = _CompositeLayerEnabled;
            _Layers.OnCreate(hook, tocObject);
        }

        /// <summary>
        /// 获取选择的图层对象
        /// </summary>
        /// <returns></returns>
        public List<ILayer> GetSelectLayers()
        {
            return _Layers.GetSelectLayers();
        }

        /// <summary>
        /// 获取指定类型的选择图层
        /// </summary>
        /// <typeparam name="T">需要的类型，如IFeatureLayer</typeparam>
        /// <returns></returns>
        public List<T> GetSelectLayers<T>()
        {
            List<ILayer> lyrs = _Layers.GetSelectLayers();
            if (lyrs == null || lyrs.Count == 0) return null;
            List<T> tlyrs = new List<T>();
            if (typeof(IFeatureClass) == typeof(T))
            {
                var q = from p in lyrs
                        where p is IFeatureLayer && ((IFeatureLayer)p).FeatureClass != null
                        select ((IFeatureLayer)p).FeatureClass;
                var lst = q.ToList();
                foreach (var l in lst) tlyrs.Add((T)l);
                return tlyrs;
            }
            List<ILayer> templyrs = lyrs.FindAll(l => l is T);
            if (templyrs == null || templyrs.Count == 0) return null;
            foreach (ILayer l in templyrs)
                tlyrs.Add((T)l);
            return tlyrs;
        }

        
        #region 联动父节点和子节点
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void LayersTree_AfterCheck(object sender, AdvTreeCellEventArgs e)
        {
            //throw new NotImplementedException();
            if (e.Action == eTreeAction.Mouse || e.Action == eTreeAction.Keyboard)
            {
                if (this.SelectedNode == null)
                    return;
                _HasChecked = false;
                _HasNoChecked = false;
                ChildNodeChange(this.SelectedNode);
                ParentNodeChange(this.SelectedNode);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        private bool _HasChecked = false;
        /// <summary>
        /// 
        /// </summary>
        private bool _HasNoChecked = false;

        /// <summary>
        /// 更改父节点状态（支持勾、不勾和半勾）
        /// </summary>
        /// <param name="node"></param>
        private void ParentNodeChange(Node node)
        {
            if (node.Parent == null)
                return;
            //bool hasChecked = false;
            //bool hasNoCheced = false;

            //for (int i = 0; i < node.Parent.Nodes.Count; i++)
            //{
            //    if (node.Parent.Nodes[i].Checked || node.Parent.Nodes[i].CheckState == CheckState.Indeterminate)
            //    {
            //        hasChecked = true;
            //    }
            //    else
            //    {
            //        hasNoCheced = true;
            //    }
            //}
            GetChildStatus(node.Parent);
            if (_HasChecked == true && _HasNoChecked == true)
            {
                node.Parent.CheckState = CheckState.Indeterminate;
            }
            else if (_HasChecked == false)
            {
                node.Parent.CheckState = CheckState.Unchecked;
            }
            else
            {
                node.Parent.CheckState = CheckState.Checked;
            }

            ParentNodeChange(node.Parent);
        }
        
        /// <summary>
        /// 
        /// </summary>
        /// <param name="node"></param>
        private void GetChildStatus(Node node)
        {
            //for (int i = 0; i < node.Nodes.Count; i++)
            //{
            //    if (node.Nodes[i].Checked || node.Nodes[i].CheckState == CheckState.Indeterminate)
            //    {
            //        _HasChecked = true;
            //    }
            //    else
            //    {
            //        _HasNoChecked = true;
            //    }
            //    if (_HasChecked && _HasNoChecked)
            //        return;
            //    if (node.Nodes.Count > 0)
            //    {
            //        GetChildStatus(node);
            //    }
            //}

            if (node.Nodes == null || node.Nodes.Count == 0)
                return;
            foreach (Node n in node.Nodes)
            {
                if (n.Checked || n.CheckState == CheckState.Indeterminate)
                {
                    _HasChecked = true;
                }
                else
                {
                    _HasNoChecked = true;
                }
                if (_HasChecked && _HasNoChecked)
                    return;
                if (n.Nodes.Count > 0)
                {
                    GetChildStatus(n);
                }
            }
        }
        /// <summary>
        /// 更新子节点状态
        /// </summary>
        /// <param name="node"></param>
        private void ChildNodeChange(Node node)
        {
            for (int i = 0; i < node.Nodes.Count; i++)
            {
                node.Nodes[i].Checked = node.Checked;
                ChildNodeChange(node.Nodes[i]);
            }
        }
        #endregion

    }
}
